home *** CD-ROM | disk | FTP | other *** search
- //
- // SetTime by pinter@p-squared.com
- //
-
- #include <afxwin.h>
- #include <afxext.h>
- #include <afxpriv.h>
- #include <time.h>
- #include "resource.h"
- #include "CWinSock.h"
-
- #define IDB_QUERY (WM_USER+1)
- #define IDB_SETCLOCK (WM_USER+2)
- #define IDT_TIMER1 (WM_USER+3)
- #define WM_USER_STREAM (WM_USER+4)
-
- #define TIMER_VALUE (1000) // Number of milliseconds per frame
- #define FRAME_WIDTH (500)
- #define FRAME_HEIGHT (300)
-
- #define BackGroundColour (RGB( 0, 0,0))
- #define ForeGroundColour (RGB(255,255,0))
-
- class CSetTimeApp : public CWinApp // Declare the application class
- {
- public:
- virtual BOOL InitInstance (); // Application class Constructor
- };
-
- CSetTimeApp SetTimeApp; // Instantiate SetTimeApp
-
- class CSetTimeWindow : public CFrameWnd // Declare the main window class
- {
- private:
- char m_pszBuffer[100]; // Communications buffer
- char m_pszServer[100]; // NTP Server name or address
- BOOL TCPmode; // TCP (Stream) Mode flag
- BOOL Primary; // Primary .vs. Backup Timebase
- BOOL UpdateClock; // Update System Clock flag
- CDC memDC; // Memory based Device Context
- CTime Current_time; // Stores new time value
- CRect rect; // Rectangle structure
- CFont *font; // Font pointer
- CMenu *menu,*popupmenu,*tempmenu; // Menu structures
- CBitmap *b1, *b2; // Button Bitmap structures
- CBitmap *newMemBitmap; // Memory DC Bitmap
- CButton *button1, *button2; // Buttons for Query & Timeset
- CWinSock *m_pWinSock; // WinSock structure
- CStatusBar m_wndStatusBar; // Status Bar
- CStreamSocket *m_pStream; // Stream socket
-
- public:
- CSetTimeWindow (); // Window class constructor
- virtual ~CSetTimeWindow (); // Window class destructor
- afx_msg void QueryTimebase ();
- afx_msg void OnSize (UINT, int, int);
- afx_msg void OnTimer (UINT);
- afx_msg void OnPaint ();
- afx_msg void OnExit ();
- afx_msg void OnAbout ();
- afx_msg void OnTCPmode ();
- afx_msg void OnRButtonDown (UINT, CPoint);
- afx_msg void OnTimeBase1 ();
- afx_msg void OnTimeBase2 ();
- afx_msg void OnUpdateSystemClock ();
- afx_msg void OnUpdateStatusBar (CCmdUI *pCmdUI);
- afx_msg void OnUpdateTCP (CCmdUI *pCmdUI);
- afx_msg void OnUpdateUDP (CCmdUI *pCmdUI);
- afx_msg void OnUpdateTICK (CCmdUI *pCmdUI);
- afx_msg void OnUpdateTOCK (CCmdUI *pCmdUI);
- afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
- afx_msg LONG OnWinSockEvent (WPARAM wParam, LPARAM lParam);
- void DrawFace (CDC &dc);
-
- DECLARE_MESSAGE_MAP ()
-
- };
-
- BEGIN_MESSAGE_MAP (CSetTimeWindow, CFrameWnd)
- ON_WM_CREATE ()
- ON_UPDATE_COMMAND_UI (ID_VIEW_STATUS_BAR,OnUpdateStatusBar)
- ON_UPDATE_COMMAND_UI (ID_INDICATOR_TCP, OnUpdateTCP)
- ON_UPDATE_COMMAND_UI (ID_INDICATOR_UDP, OnUpdateUDP)
- ON_UPDATE_COMMAND_UI (ID_INDICATOR_TICK, OnUpdateTICK)
- ON_UPDATE_COMMAND_UI (ID_INDICATOR_TOCK, OnUpdateTOCK)
- ON_WM_SIZE ()
- ON_WM_TIMER ()
- ON_BN_CLICKED (IDB_QUERY, QueryTimebase)
- ON_BN_CLICKED (IDB_SETCLOCK, OnUpdateSystemClock)
- ON_COMMAND (ID_APP_EXIT, OnExit)
- ON_COMMAND (ID_APP_ABOUT, OnAbout)
- ON_COMMAND (IDM_TCP_MODE, OnTCPmode)
- ON_WM_RBUTTONDOWN ()
- ON_COMMAND (IDM_TIMEBASE1, OnTimeBase1)
- ON_COMMAND (IDM_TIMEBASE2, OnTimeBase2)
- ON_MESSAGE (WM_USER_STREAM, OnWinSockEvent)
- END_MESSAGE_MAP ()
-
- static UINT indicators[] = // Array of Status Bar indicators
- {
- ID_SEPARATOR,
- ID_INDICATOR_TCP,
- ID_INDICATOR_UDP,
- ID_INDICATOR_TICK,
- ID_INDICATOR_TOCK
- };
-
- BOOL CSetTimeApp::InitInstance () // InitInstance called when
- { // the application first executes
- m_pMainWnd = new CSetTimeWindow ();
- m_pMainWnd->ShowWindow (m_nCmdShow);
- m_pMainWnd->UpdateWindow ();
-
- SetDialogBkColor();
-
- return TRUE;
- }
-
- CSetTimeWindow::CSetTimeWindow() : TCPmode (TRUE), // The window class constructor
- Primary (TRUE),
- UpdateClock (FALSE)
- {
- CBrush BackGroundBrush (BackGroundColour);
-
- const char *pszWindowClass = AfxRegisterWndClass (CS_HREDRAW|
- CS_VREDRAW|
- CS_BYTEALIGNCLIENT|
- CS_BYTEALIGNWINDOW|
- CS_SAVEBITS,
- NULL,
- BackGroundBrush,
- AfxGetApp()->LoadIcon (IDI_ICON1));
-
- Create (pszWindowClass, // Create the window itself
- "Network Time Protocol Client",
- WS_OVERLAPPEDWINDOW,
- CRect (0, 0, FRAME_WIDTH, FRAME_HEIGHT),
- NULL,
- MAKEINTRESOURCE(IDR_MENU1)); // *need* to pre-load the menu
-
- CenterWindow (GetDesktopWindow());
-
- menu = new CMenu();
- menu-> LoadMenu (MAKEINTRESOURCE(IDR_MENU1));
-
- popupmenu = new CMenu();
- popupmenu-> LoadMenu (MAKEINTRESOURCE(IDR_MENU2));
-
- b1 = new CBitmap(); b1->LoadBitmap (MAKEINTRESOURCE(IDB_BITMAP1));
- b2 = new CBitmap(); b2->LoadBitmap (MAKEINTRESOURCE(IDB_BITMAP2));
-
- menu-> ModifyMenu (IDM_TIMEBASE1, MF_BYCOMMAND, IDM_TIMEBASE1, b1);
- menu-> ModifyMenu (IDM_TIMEBASE2, MF_BYCOMMAND, IDM_TIMEBASE2, b2);
-
- SetMenu (menu);
-
- DrawMenuBar ();
-
- ShowControlBar (&m_wndStatusBar, TRUE, FALSE);
-
- LoadAccelTable (MAKEINTRESOURCE(IDR_ACCELERATOR1));
-
- GetClientRect (rect); // Get rectangle dimensions
-
- button1 = new CButton(); // Create a Static Button
- button1-> Create ("Query Navy Timebase",
- WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
- CRect (rect.left, rect.top, rect.right, rect.top+20),
- this,
- IDB_QUERY);
-
- button2= new CButton(); // Create a Static Button
- button2-> Create ("Correct System Clock",
- WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
- CRect (rect.left, rect.bottom-40, rect.right, rect.bottom-20),
- this,
- IDB_SETCLOCK);
-
- CClientDC dc (this); // Get a Client area DC
-
- memDC.CreateCompatibleDC (&dc); // Create a clientarea compatible DC
-
- newMemBitmap = new CBitmap; // Instantiate a new Bitmap
- newMemBitmap-> CreateCompatibleBitmap (&dc, rect.Width(), rect.Height());
- CBitmap *pOldMemBitmap = memDC.SelectObject (newMemBitmap);
- memDC.PatBlt (0,0, FRAME_WIDTH, FRAME_HEIGHT, BLACKNESS);
- memDC.SelectObject (pOldMemBitmap); // Prevents memory leaks
-
- m_pWinSock = NULL; // Reset Winsock pointer
- m_pStream = NULL; // Reset Stream pointer
- (*m_pszBuffer) = '\0'; // Reset communication buffer
-
- m_pWinSock = new CWinSock; // Instantiate a new Winsock object
-
- if (m_pWinSock->Startup() == CWINSOCK_NOERROR)
- m_wndStatusBar.SetPaneText (0, "WinSock Initialized", TRUE);
- else
- {
- m_wndStatusBar.SetPaneText (0, "WinSock Initialization FAILED", TRUE);
- delete m_pWinSock;
- m_pWinSock = NULL;
- return;
- }
-
- lstrcpy (m_pszServer, "tick.usno.navy.mil");// Preset default timebase
-
- SetTimer (IDT_TIMER1, TIMER_VALUE, NULL); // Set timer for frame refresh
-
- Current_time= CTime::GetCurrentTime(); // Preload current time field
-
- button2-> EnableWindow(FALSE); // Disable updates till query done
-
- font = new CFont; // Create a new font object
-
- }
-
- CSetTimeWindow::~CSetTimeWindow()
-
- {
- if (m_pStream)
- {
- m_pStream-> DestroySocket();
- delete m_pStream;
- m_pStream = NULL;
- }
-
- if (m_pWinSock)
- {
- m_pWinSock->Shutdown();
- delete m_pWinSock;
- m_pWinSock = NULL;
- }
-
- delete button1; // prevent memory leaks...
- delete button2;
- b1-> DeleteObject(); delete b1;
- b2-> DeleteObject(); delete b2;
- delete menu;
- delete popupmenu;
- font-> DeleteObject(); delete font;
- newMemBitmap-> DeleteObject(); delete newMemBitmap;
-
- }
-
- int CSetTimeWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
-
- if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
-
- if (!m_wndStatusBar.Create(this) ||
- !m_wndStatusBar.SetIndicators (indicators, sizeof(indicators)/sizeof (UINT)))
- {
- TRACE0("Failed to create status bar\n");
- return -1;
- }
-
- m_wndStatusBar.SetPaneInfo (0, m_wndStatusBar.GetItemID (0), SBPS_STRETCH, NULL);
- return 0;
- }
-
- void CSetTimeWindow::QueryTimebase()
- {
- m_wndStatusBar.SetPaneText (0, "Connecting to Internet...", TRUE);
- m_wndStatusBar.SendMessage (WM_IDLEUPDATECMDUI);// Force an update to the Status Bar
- m_wndStatusBar.UpdateWindow();
-
- button1-> EnableWindow(FALSE);
-
- m_pStream = new CStreamSocket (this, WM_USER_STREAM);
-
- if (m_pStream->CreateSocket() == CWINSOCK_NOERROR)
- {
- m_wndStatusBar.SetPaneText (0, "Stream Created. Waiting to Connect...", TRUE);
- }
- else {
- m_wndStatusBar.SetPaneText (0, "Stream Create FAILED. Verify Internet Link.", TRUE);
- delete m_pStream;
- m_pStream = NULL;
- button1-> EnableWindow(TRUE);
- }
-
- if (m_pStream->Connect(m_pszServer, 37) == CWINSOCK_NOERROR)
- {
- m_wndStatusBar.SetPaneText (0, "Connected; waiting for Correct Time...", TRUE);
- }
- else
- {
- m_wndStatusBar.SetPaneText (0, "Connect FAILED. Verify Internet Link.", TRUE);
- delete m_pStream;
- m_pStream = NULL;
- button1-> EnableWindow(TRUE);
- }
- }
-
- void CSetTimeWindow::OnUpdateSystemClock()
- {
- button2-> EnableWindow(FALSE);
- UpdateClock = TRUE;
- QueryTimebase();
- }
-
- void MakeFont (CFont *font, int x)
- {
- font-> DeleteObject();
- font-> CreateFont (x, 0, 0, 0, FW_THIN, 0, 0, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS,
- CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
- DEFAULT_PITCH | TMPF_TRUETYPE, NULL);
- }
-
- void CSetTimeWindow::OnSize (UINT nType, int cx, int cy)
- {
- int x = 2;
- CRect r;
- CClientDC dc (this);
-
- CStatusBar *pStatusBar = (CStatusBar *) AfxGetApp()->m_pMainWnd->GetDescendantWindow (ID_VIEW_STATUS_BAR);
-
- GetClientRect (&rect);
-
- button1-> MoveWindow (CRect (rect.left, rect.top, rect.right, rect.top+20));
- button2-> MoveWindow (CRect (rect.left, rect.bottom-40, rect.right, rect.bottom-20));
- rect.InflateRect (0, -20, 0, -40); // Account for buttons in client area
-
- ShowControlBar (pStatusBar, TRUE, FALSE); // Show Status Bar in new location
-
- do
- {
- x += 10; // try creating a font at size x
- r = rect; // calc size of string with that font
-
- MakeFont (font, x); // try a font on for size
-
- CFont *pOldFont = memDC.SelectObject (font);// select the font onto DC
-
- memDC.DrawText (Current_time.Format ("%X"),
- -1,
- r,
- DT_CALCRECT | DT_SINGLELINE | DT_CENTER | DT_VCENTER);
-
- memDC.SelectObject (pOldFont); // prevent memory leaks
-
- } while (rect == (r | rect)); // halt when string overflows the rect
-
- MakeFont (font, x-10); // Adjust final fontsize for 'drawface'
-
- GetClientRect (&rect);
-
- newMemBitmap-> DeleteObject();
- newMemBitmap-> CreateCompatibleBitmap (&dc, rect.Width(), rect.Height());
- }
-
- void CSetTimeWindow::OnTimer (UINT id)
- {
- CClientDC dc (this);
- DrawFace (dc);
- }
-
- void CSetTimeWindow::OnPaint ()
- {
- CPaintDC dc (this);
- DrawFace (dc);
- }
-
- void CSetTimeWindow::OnExit()
- {
- DestroyWindow();
- }
-
- void CSetTimeWindow::OnAbout()
- {
- MessageBox ("Bearware by Pete Pinter (pinter@p-squared.com)", "About SetTime");
- }
-
- void CSetTimeWindow::OnTCPmode()
- {
- /******** if (TCPmode)
- {
- menu-> CheckMenuItem (IDM_TCP_MODE, MF_BYCOMMAND|MF_UNCHECKED);
- popupmenu-> CheckMenuItem (IDM_TCP_MODE, MF_BYCOMMAND|MF_UNCHECKED);
- menu-> CheckMenuItem (IDM_UDP_MODE, MF_BYCOMMAND|MF_CHECKED);
- popupmenu-> CheckMenuItem (IDM_UDP_MODE, MF_BYCOMMAND|MF_CHECKED);
- }
- else
- {
- menu-> CheckMenuItem (IDM_TCP_MODE, MF_BYCOMMAND|MF_CHECKED);
- popupmenu-> CheckMenuItem (IDM_TCP_MODE, MF_BYCOMMAND|MF_CHECKED);
- menu-> CheckMenuItem (IDM_UDP_MODE, MF_BYCOMMAND|MF_UNCHECKED);
- popupmenu-> CheckMenuItem (IDM_UDP_MODE, MF_BYCOMMAND|MF_UNCHECKED);
- }
- TCPmode =! TCPmode;********/ // toggle TCP mode flag
- }
-
- void CSetTimeWindow::OnRButtonDown (UINT x, CPoint p)
- {
- ClientToScreen (&p); // convert client to screen coordinates
- tempmenu = popupmenu->GetSubMenu (0);
- tempmenu-> TrackPopupMenu (TPM_CENTERALIGN|TPM_RIGHTBUTTON, p.x, p.y, this);
- }
-
- void CSetTimeWindow::OnTimeBase1 ()
- {
- Primary = TRUE;
- lstrcpy (m_pszServer, "tick.usno.navy.mil");
- m_wndStatusBar.SetPaneText (0, "tick.usno.navy.mil selected", TRUE);
- }
-
- void CSetTimeWindow::OnTimeBase2 ()
- {
- Primary = FALSE;
- lstrcpy (m_pszServer, "tock.usno.navy.mil");
- m_wndStatusBar.SetPaneText (0, "tock.usno.navy.mil selected", TRUE);
- }
-
- void CSetTimeWindow::OnUpdateStatusBar (CCmdUI *pCmdUI)
- {
- pCmdUI->Enable (TRUE);
- }
-
- void CSetTimeWindow::OnUpdateTCP (CCmdUI *pCmdUI)
- {
- if (TCPmode) pCmdUI->Enable (TRUE);
- else pCmdUI->Enable (FALSE);
- }
-
- void CSetTimeWindow::OnUpdateUDP (CCmdUI *pCmdUI)
- {
- if (TCPmode) pCmdUI->Enable (FALSE);
- else pCmdUI->Enable (TRUE);
- }
-
- void CSetTimeWindow::OnUpdateTICK (CCmdUI *pCmdUI)
- {
- if (Primary) pCmdUI->Enable (TRUE);
- else pCmdUI->Enable (FALSE);
- }
-
- void CSetTimeWindow::OnUpdateTOCK (CCmdUI *pCmdUI)
- {
- if (!Primary) pCmdUI->Enable (TRUE);
- else pCmdUI->Enable (FALSE);
- }
-
- LONG CSetTimeWindow::OnWinSockEvent (WPARAM wParam, LPARAM lParam)
- {
- int nLength; // Length of Data read/written
- char pszMessage[100]; // StatusBar text buffer
- void *pDataWritten; // Pointer to data sent
- time_t *pDataRead; // Pointer to time value read
- time_t Navy_time; // Time value from Navy
- CString Delta; // Contains delta time as a string
- CTimeSpan Span; // Holds delta time span of clocks
- SYSTEMTIME Timecell; // Holds System specific time value
-
- switch (wParam)
- {
- case CWINSOCK_DONE_WRITING: // lParam points to sent data
- pDataWritten = (LPVOID) lParam;
- wsprintf (pszMessage, "OnWinSockEvent: Data Sent (%s)", pDataWritten);
- m_wndStatusBar.SetPaneText (0, pszMessage, TRUE);
- (*m_pszBuffer) = '\0'; // same as (*pDataWritten) = '\0'
- break;
-
- case CWINSOCK_ERROR_WRITING: // lParam points to failed sent data
- pDataWritten = (LPVOID) lParam;
- wsprintf (pszMessage, "OnWinSockEvent: Error Sending Data: (%s)", pDataWritten);
- m_wndStatusBar.SetPaneText (0, pszMessage, TRUE);
- (*m_pszBuffer) = '\0'; // same as (*pDataWritten) = '\0'
- break;
-
- case CWINSOCK_DONE_READING: // lParam = number of data chunks in queue
-
- pDataRead = (time_t *) m_pStream->Read (&nLength);
-
- if (pDataRead == NULL)
- {
- m_wndStatusBar.SetPaneText (0, "Selected Timebase returned NULL data!", TRUE);
- free (pDataRead);
- break;
- }
-
- Navy_time = ntohl (*pDataRead) - 2208988800; // Offset to Jan 1, 1970
-
- Current_time= Navy_time; // Store as a CTime object
-
- if (UpdateClock)
- {
- UpdateClock = FALSE; // reset clock update flag
- Timecell.wYear = Current_time.GetYear();
- Timecell.wMonth = Current_time.GetMonth();
- Timecell.wDay = Current_time.GetDay();
- Timecell.wHour = Current_time.GetHour();
- Timecell.wMinute = Current_time.GetMinute();
- Timecell.wSecond = Current_time.GetSecond();
- Timecell.wMilliseconds = TIMER_VALUE/2; // fake transit time
- SetLocalTime (&Timecell); // update system clock
- }
-
- Span = CTime::GetCurrentTime() - Current_time;
- Delta = Current_time.Format("Timebase Clock: %c. ") + Span.Format("Delta: %D days %H:%M:%S");
-
- m_wndStatusBar.SetPaneText (0, Delta, TRUE);
-
- button1-> EnableWindow(TRUE);
- button2-> EnableWindow(TRUE);
-
- free (pDataRead);
- break;
-
- case CWINSOCK_ERROR_READING:
- break;
-
- case CWINSOCK_YOU_ARE_CONNECTED:
- break;
-
- case CWINSOCK_LOST_CONNECTION: // Server closed the connection
- if (m_pStream)
- {
- m_pStream-> DestroySocket();
- delete m_pStream;
- m_pStream = NULL;
- }
- break;
-
- default:
- break;
- }
- return 0;
- }
-
- void CSetTimeWindow::DrawFace (CDC &dc)
- {
- Current_time = CTime::GetCurrentTime(); // Get current system time
-
- GetClientRect (&rect); // Get current client area size
-
- CFont *pOldFont = memDC.SelectObject (font); // Load calculated font into DC
- CBitmap *pOldBitMap = memDC.SelectObject (newMemBitmap);
-
- memDC.FillSolidRect (rect, BackGroundColour); // Fill with background colour
- memDC.SetTextColor (ForeGroundColour); // Set foreground text colour
- memDC.SetBkColor (BackGroundColour); // Set background text colour
-
- rect.InflateRect (0, -20, 0, -40); // Adjust for both buttons
-
- memDC.DrawText (Current_time.Format ("%X"), // Write current time to screen
- -1,
- rect,
- DT_SINGLELINE |DT_CENTER | DT_VCENTER);
-
- dc.BitBlt (0, 20, rect.Width(), rect.Height(),
- &memDC, 0, 20, SRCCOPY); // Blast memory DC to screen
-
- memDC.SelectObject (pOldFont); // Prevent memory leaks
- memDC.SelectObject (pOldBitMap);
- }
-